package ws

import (
	"svr/src/conf"
	"svr/src/logs"
	"svr/src/msg"
	"svr/src/xutil"
	"time"

	"google.golang.org/protobuf/proto"
)

type MsgTask struct {
	Dev       *DeviceInfo
	Msg       *MsgInfo
	MsgR      proto.Message
	StartTime time.Time
}

// var NameRegisterDeviceR string

func init() {
	// MapConnectors = &xutil.Map{}
	// MapConnectors.Init()
	// m := &msg.RegisterDeviceR{}
	// NameRegisterDeviceR = string(proto.MessageReflect(m).Descriptor().FullName().Name())
}

// 回消息给来处，m消息数据，mc0传过来的，dest最终收消息的设备
func (mt *MsgTask) ReturnMsg(ma proto.Message, errs ...*msg.Error) *msg.Error {
	var mer *msg.Error
	if errs != nil && len(errs) > 0 {
		mer = errs[0]
	}
	mer = mt.Dev.ReturnMsg(ma, mer, mt)
	mt.PrintLog(ma, mer)
	return mer
}

func (mt *MsgTask) End(errs ...*msg.Error) *msg.Error {
	var mer *msg.Error
	if errs != nil && len(errs) > 0 {
		mer = errs[0]
	}
	mt.PrintLog(nil, mer)
	return mer
}

func (mt *MsgTask) PrintLog(ma proto.Message, err *msg.Error) {
	dur := time.Now().Sub(mt.StartTime)
	if err != nil {
		if ma != nil {
			logs.Infof("msg:%+v error. cost:%+v, r:%+v ,err:%+v,", mt.Msg.Conf.Name, dur, mt.MsgR, err)
		} else {
			logs.Infof("msg:%+v end error. cost:%+v, r:%+v ,err:%+v,", mt.Msg.Conf.Name, dur, mt.MsgR, err)
		}
	} else {
		if ma != nil {
			logs.Infof("msg:%+v succed. cost:%+v, r:%+v ,a:%+v", mt.Msg.Conf.Name, dur, mt.MsgR, ma)
		} else {
			logs.Infof("msg:%+v end. cost:%+v, r:%+v", mt.Msg.Conf.Name, dur, mt.MsgR)
		}
	}
}

type MsgInfo struct {
	Conf *msg.MsgConfig
	Data []byte
}

// 判断是否是自己要处理的消息
func (mi *MsgInfo) IsSelfMsg() bool {
	return mi.Conf.Dest == conf.ServerConfig.ServerType || mi.Conf.Dest == msg.DeviceType_JustDispose
}

// 转发消息给该去的地方
func (mi *MsgInfo) SendMsgToDest() *msg.Error {
	var di *DeviceInfo
	var err *msg.Error
	if mi.Conf.DestIp != "" { //客户端会寻找固定的战斗服用这个。转发服找客户端也用这个。
		di, err = GetConnectDeviceByIp(mi.Conf.Dest, mi.Conf.DestIp)
	} else {
		di, err = GetConnectDevice(mi.Conf.Dest, false) //获取目标服务器
	}
	if err != nil { //目标服务器不存在
		return err
	}
	return di.SendMessageData(mi.ToBytes()) //转发过去
}

// 转为byte数组
func (mi *MsgInfo) ToBytes() []byte {
	bs0, _ := proto.Marshal(mi.Conf)
	wr := xutil.NewWriterBuf(len(bs0) + len(mi.Data) + 4) //4是两个int16，表示两个[]byte的长度
	wr.WriteBytes(bs0)
	wr.WriteBytes(mi.Data)
	return wr.Bytes()
}

func (mi *MsgInfo) CheckError() bool {
	if mi.Conf == nil {
		logs.Errorf("MsgConfig is nil")
		return true
	}
	if mi.Conf.Err != nil {
		err := mi.Conf.Err
		logs.Errorf("Msg:%s is have error. code:%v, result:%s", mi.Conf.Name, err.Code, err.Result)
		return true
	}
	return false
}

func CreateMsgError(code msg.ErrCode, result string) *msg.Error {
	return &msg.Error{Code: code, Result: result}
}
